#!/bin/bash

# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is XPIt.
#
# The Initial Developer of the Original Code is
# Nikolay "Shutnik" Frantsev <code [at] frantsev (dot) ru>.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# ***** END LICENSE BLOCK *****



# ===== About =====

# XPIt is simple SH build-script for your Mozilla add-ons
# Written by Nikolay "Shutnik" Frantsev <code [at] frantsev (dot) ru>

# Last modified: Mon Nov 29 11:01:40 EET 2010
# Latest version at <http://frantsev.ru/pub/mozilla/xpit/> or <http://moz-xpit.googlecode.com/>

# Just put it into your add-on catalog and run!

# XPI it!

# ===== /About =====



# ===== Config =====

# do not pack that files to JAR-archive
JAR_SKIP="*~ *.jar *.git/* *.svn/* *.cvs/*"

# do not pack that files to XPI-archive
XPI_SKIP="*~ *.xpi update.rdf xpit.sh *.git/* *.svn/* *.cvs/*"

# display colors
COLORED=true

# ===== /Config =====



# ===== Constants =====

# remember current path
ROOT_PATH=`pwd`

# steps counter
STEP=0

# ===== Constants =====



# ===== Functions =====

ERROR() {
	if [ -n "$TMP_PATH" ] && [ -d "$TMP_PATH" ]
	then
		rm -rf "$TMP_PATH"
	fi
	if [ ! -z "$1" ]
	then
		if [ -n "$COLORED" ] && [ $COLORED = true ]
		then
			echo -e "\033[01;31mERROR:\033[0m $1"
			echo -e "\033[01;31mBuild failed!\033[0m"
		else
			echo "ERROR: $1"
			echo "Build failed!"
		fi
		exit
	fi
}

SUCCESS() {
	if [ ! -z "$1" ]
	then
		if [ -n "$COLORED" ] && [ $COLORED = true ]
		then
			echo -e "\033[01;32m$1\033[0m"
		else
			echo "$1"
		fi
	fi
}

INFO() {
	if [ ! -z "$1" ]
	then
		if [ -n "$2" ]
		then
			if [ $2 = true ]
			then
				echo -n " $1... "
			else
				echo "Step#$STEP: $1:"
				STEP=$((STEP+1))
			fi
		else
			echo -n "Step#$STEP: $1... "
			STEP=$((STEP+1))
		fi
	fi
}

# ===== /Functions =====



# ===== Copying files and checking the basic structure =====

INFO "Copying files and checking the basic structure"

# making temporary catalog
TMP_PATH=`mktemp -d 2> /dev/null`
if [ ! -d "$TMP_PATH" ]
then
	ERROR "Cannot create a temporary catalog!"
fi

# copying files into it ...
cp -r "$ROOT_PATH/." "$TMP_PATH"

# ... and going there
cd "$TMP_PATH"

# fix file permissions ...
chmod -R 0755 *

# .. and reset modification time
find . | xargs touch

# checking install.rdf file exists
if [ ! -f "install.rdf" ]
then
	ERROR "No Install Manifest file found!"
fi

# checking chrome.manifest file exists
if [ ! -f "chrome.manifest" ]
then
	ERROR "No Chrome Registration file found!"
fi

# checking chrome catalog exists
if [ ! -f "chrome.manifest" ]
then
	ERROR "No chrome catalog found!"
fi

SUCCESS "DONE"

# ===== /Copying files and checking the basic structure =====



# ===== Processing Install Manifest file =====

INFO "Processing Install Manifest file"

# getting extension name
NAME=`grep -Eo -m1 ":name=\"[^\"]+\"" install.rdf | sed -r "s/^:name=\"//;s/\"$//;s/[[:space:]]+/_/g;s/.*/\L&/;s/&amp;/\&/g"`
if [ -z "$NAME" ]
then
	NAME=`grep -Eo -m1 ":name>[^<]+<" install.rdf | sed -r "s/^:name>//;s/<$//;s/[[:space:]]+/_/g;s/.*/\L&/;s/&amp;/\&/g"`
	if [ -z "$NAME" ]
	then
		ERROR "Cannot find extension name, check your install.rdf!"
	fi
fi

# getting extension version
VERSION=`grep -Eo -m1 ":version=\"[^\"]+\"" install.rdf | sed -r "s/^:version=\"//;s/\"$//"`
if [ -z "$VERSION" ]
then
	VERSION=`grep -Eo -m1 ":version>[^<]+<\/" install.rdf | sed -r "s/^:version>//;s/<\/$//"`
	if [ -z "$VERSION" ]
	then
		ERROR "Cannot find extension version, check your install.rdf!"
	fi
fi

# declare XPI name
XPI_NAME=$NAME-$VERSION.xpi

SUCCESS "DONE"

# ===== /Processing Install Manifest file =====



# ===== Processing Chrome Registration file =====

INFO "Processing Chrome Registration file" false


# ===== Checking file structure =====

INFO "Checking file structure" true

# getting package name
PACKAGE_EXP="^[[:space:]]*content[[:space:]]+"
PACKAGE_NAME=`grep -Eo -m1 "$PACKAGE_EXP[^[:space:]]+" chrome.manifest | sed -r "s/$PACKAGE_EXP//"`
if [ -z "$PACKAGE_NAME" ]
then
	ERROR "Cannot find any content declaration, check your chrome.manifest!"
fi

# checking existing chrome catalog
CHROME_EXP="$PACKAGE_EXP$PACKAGE_NAME[[:space:]]+"
CHROME_PATH=`grep -Eo -m1 "$CHROME_EXP[^[:space:]]+" chrome.manifest | sed -r "s/$CHROME_EXP(file:)?//"`
if [ ! -d "$CHROME_PATH" ]
then
	ERROR "Declared chrome catalog $CHROME_PATH does not exists, check your chrome.manifest!"
fi

# declaring JAR name
JAR_NAME=$PACKAGE_NAME.jar

SUCCESS "DONE"

# ===== /Checking file structure =====


# ===== Checking locales structure =====

INFO "Checking locales structure" true

# checking declared locales exists
LOCALES_EXP="^[[:space:]]*locale[[:space:]]+$PACKAGE_NAME[[:space:]]+"
LOCALES_PATHS_EXP="$LOCALES_EXP[^[:space:]]+[[:space:]]+"
LOCALES_PATHS=`grep -Eo "$LOCALES_PATHS_EXP[^[:space:]]+" chrome.manifest | sed -r "s/$LOCALES_PATHS_EXP(file:)?//"`
for LOCALE_PATH in $LOCALES_PATHS
do
	if [ ! -d "$LOCALE_PATH" ]
	then
		ERROR "Declared locale $LOCALE_PATH does not exists, check your locales catalog!"
	fi
done

# checking existing locales declared
LOCALES_DECLARED=`grep -Eo "$LOCALES_EXP[^[:space:]]+" chrome.manifest | sed -r "s/$LOCALES_EXP//"`
if [ -n "$LOCALES_DECLARED" ]
then
	LOCALES_CATALOGS=`ls "$LOCALE_PATH/.."`
	for LOCALE_CATALOG in $LOCALES_CATALOGS
	do
		EXISTS=0
		for LOCALE_DECLARED in $LOCALES_DECLARED
		do
			if [ "$LOCALE_CATALOG" = "$LOCALE_DECLARED" ]
			then
				EXISTS=1
				break
			fi
		done
		if [ $EXISTS = 0 ]
		then
			ERROR "Existing $LOCALE_CATALOG locale is not declared, check your chrome.manifest!"
		fi
	done
fi

SUCCESS "DONE"

# ===== /Checking locales structure =====


# ===== Replacing file-paths with JAR-paths =====

INFO "Replacing file-paths with JAR-paths" true

# replacing file-paths with JAR-paths at content and resource block
sed -i -r "s/((content|resource)[[:space:]]+[^[:space:]]+[[:space:]]+)file:chrome\//\1jar:chrome\/$JAR_NAME\!\//" chrome.manifest

# replacing file-paths with JAR-paths at skin and locale blocks
sed -i -r "s/(skin|locale)([[:space:]]+$PACKAGE_NAME[[:space:]]+[^[:space:]]+[[:space:]]+)file:chrome\//\1\2jar:chrome\/$JAR_NAME\!\//" chrome.manifest

SUCCESS "DONE"

# ===== /Replacing file-paths with JAR-paths =====


# ===== /Processing Chrome Registration file =====



# ===== Saving build info =====

INFO "Saving build info"

{
	echo "Build date: "`date +"%A, %d %B %Y"`
	echo "Build system: "`lsb_release -ds 2> /dev/null || uname -o`
	echo
	echo "Builded with xpit.sh (<http://frantsev.ru/pub/mozilla/xpit/> or <http://moz-xpit.googlecode.com/>)"
} > build.txt

SUCCESS "DONE"

# ===== /Saving build info =====



# ===== Packing chrome archive =====

INFO "Packing chrome archive"

# going chrome catalog
cd "chrome"

# removing old archive
rm -f "$JAR_NAME"

# packing new archive (without compression)
zip -r -q -0 -X "../$JAR_NAME" . -x $JAR_SKIP

# going add-on catalog
cd "$TMP_PATH"

# removing old chrome catalog
rm -rf "chrome/"

# making new chrome catalog ...
mkdir "chrome/"

# ... and moving archive there
mv "$JAR_NAME" "chrome/"

SUCCESS "DONE"

# ===== /Packing chrome archive =====



# ===== Packing add-on archive =====

INFO "Packing add-on archive"

# removing old archive
rm -f "$XPI_NAME"

# packing new archive (maximum compression)
zip -r -q -9 -X "$XPI_NAME" . -x $XPI_SKIP

SUCCESS "DONE"

# ===== /Packing add-on archive =====



# ===== Cleaning up temporary files =====

INFO "Cleaning up temporary files"

# moving XPI to old add-on catalog
mv "$XPI_NAME" "$ROOT_PATH"

# going old add-on catalog
cd "$ROOT_PATH"

# removing temporary catalog
ERROR

SUCCESS "DONE"

# ===== /Cleaning up temporary files =====



# ===== Getting SHA1 checksum =====

CHECKSUM=`sha1sum "$XPI_NAME" | grep -Eo -m1 "^[[:alnum:]]+"`
if [ ! -z "$CHECKSUM" ]
then
	INFO "Getting SHA1 checksum"
	SUCCESS "$CHECKSUM"
fi

# ===== /Getting SHA1 checksum =====



# ===== Processing update file =====

if [ -f "update.rdf" ] && [ ! -z "$VERSION" ] && [ ! -z "$CHECKSUM" ] && [ ! -z "$CHECKSUM" ]
then
	INFO "Processing update file"

	rm -f "$NAME.rdf"

	cp "update.rdf" "$NAME.rdf"

	VERSION=`echo $VERSION | sed "s/&/\\\\\\&amp;/g"`
	XPI_NAME=`echo $XPI_NAME | sed "s/&/\\\\\\&amp;/g"`
	CHECKSUM=`echo $CHECKSUM | sed "s/&/\\\\\\&amp;/g"`

	sed -i "s/%FILE_VERSION%/$VERSION/g;s/%FILE_NAME%/$XPI_NAME/g;s/%FILE_CHECKSUM%/$CHECKSUM/g" "$NAME.rdf"

	SUCCESS "DONE"
fi

# ===== /Processing update file =====



# ===== Run mccoy =====

if [ -x "/usr/bin/mccoy" ]
then
	INFO "Running McCoy"

	mccoy &

	SUCCESS "DONE"
fi

# ===== /Run mccoy =====



SUCCESS "Build done!"
